<template>
  <el-dialog
    v-model="dialogVisible"
    :title="'请求详情 - ' + (requestItem?.method || '') + ' ' + (requestItem?.url || '')"
    width="80%"
    top="5vh"
    @closed="handleClose"
  >
    <div v-if="requestItem" class="request-details">
      <el-tabs v-model="activeTab">
        <el-tab-pane label="请求信息" name="request">
          <div class="details-section">
            <h3>基本信息</h3>
            <div class="info-list">
              <div class="info-item info-item-url">
                <label>URL:</label>
                <span>{{ requestItem.url }}</span>
              </div>
              <div class="info-row">
                <div class="info-item">
                  <label>方法：</label>
                  <span>{{ requestItem.method }}</span>
                </div>
                <div class="info-item">
                  <label>时间：</label>
                  <span>{{ formatTime(requestItem.timestamp) }}</span>
                </div>
                <div class="info-item">
                  <label>响应时间：</label>
                  <span>{{ requestItem.responseTime || 'N/A' }}ms</span>
                </div>
              </div>
            </div>
          </div>

          <div class="details-section" v-if="requestItem.headers && Object.keys(requestItem.headers).length > 0">
            <h3>请求头</h3>
            <div class="headers-list">
              <div v-for="(value, key) in requestItem.headers" :key="key" class="header-item">
                <strong>{{ key }}:</strong> {{ value }}
              </div>
            </div>
          </div>

          <div class="details-section" v-if="requestItem.body">
            <h3>请求体</h3>
            <el-input
              v-model="formattedRequestBody"
              type="textarea"
              :rows="10"
              readonly
              class="request-body"
            />
          </div>
        </el-tab-pane>

        <el-tab-pane label="响应信息" name="response" v-if="requestItem.response">
          <div class="details-section">
            <h3>响应状态</h3>
            <div class="info-grid">
              <div class="info-item">
                <label>状态码：</label>
                <el-tag :type="getStatusType(requestItem.status)">
                  {{ requestItem.status }} {{ requestItem.statusText }}
                </el-tag>
              </div>
              <div class="info-item">
                <label>内容类型：</label>
                <span>{{ requestItem.response.headers['content-type'] || 'N/A' }}</span>
              </div>
            </div>
          </div>

          <div class="details-section" v-if="requestItem.response.headers">
            <h3>响应头</h3>
            <div class="headers-list">
              <div v-for="(value, key) in requestItem.response.headers" :key="key" class="header-item">
                <strong>{{ key }}:</strong> {{ value }}
              </div>
            </div>
          </div>

          <div class="details-section" v-if="requestItem.response.data">
            <h3>响应体</h3>
            <el-input
              v-model="formattedResponseBody"
              type="textarea"
              :rows="15"
              readonly
              class="response-body"
            />
          </div>
        </el-tab-pane>
      </el-tabs>
    </div>
  </el-dialog>
</template>

<script setup>
import { ref, computed, watch } from 'vue'

const props = defineProps({
  visible: {
    type: Boolean,
    default: false
  },
  requestItem: {
    type: Object,
    default: null
  }
})

const emit = defineEmits(['update:visible', 'close'])

const dialogVisible = ref(false)
const activeTab = ref('request')

// 监听 visible 变化
watch(() => props.visible, (newVal) => {
  dialogVisible.value = newVal
  if (newVal) {
    activeTab.value = 'request'
  }
})

// 监听 dialogVisible 变化
watch(dialogVisible, (newVal) => {
  if (newVal !== props.visible) {
    emit('update:visible', newVal)
  }
})

// 格式化时间
const formatTime = (timestamp) => {
  const date = new Date(timestamp)
  return date.toLocaleString('zh-CN')
}

// 获取状态码标签类型
const getStatusType = (status) => {
  if (!status) return 'info'
  if (status >= 200 && status < 300) return 'success'
  if (status >= 300 && status < 400) return 'info'
  if (status >= 400 && status < 500) return 'warning'
  return 'danger'
}

// 格式化请求体
const formattedRequestBody = computed(() => {
  if (!props.requestItem?.body) return ''
  try {
    if (typeof props.requestItem.body === 'object') {
      return JSON.stringify(props.requestItem.body, null, 2)
    } else {
      return props.requestItem.body
    }
  } catch (e) {
    return props.requestItem.body
  }
})

// 格式化响应体
const formattedResponseBody = computed(() => {
  if (!props.requestItem?.response?.data) return ''
  try {
    if (typeof props.requestItem.response.data === 'object') {
      return JSON.stringify(props.requestItem.response.data, null, 2)
    } else {
      return props.requestItem.response.data
    }
  } catch (e) {
    return props.requestItem.response.data
  }
})

// 处理关闭
const handleClose = () => {
  emit('close')
}
</script>

<style scoped>
.request-details {
  max-height: 70vh;
  overflow-y: auto;
}

.details-section {
  margin-bottom: 24px;
}

.details-section h3 {
  color: #303133;
  margin-bottom: 16px;
  font-size: 16px;
  border-bottom: 1px solid #ebeef5;
  padding-bottom: 8px;
}

.info-list {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.info-item {
  display: flex;
  align-items: center;
  gap: 8px;
}

.info-item label {
  color: #606266;
  font-weight: 500;
  min-width: 80px;
}

.info-item-url {
  width: 100%;
}

.info-item-url span {
  word-break: break-all;
  color: #409eff;
}

.info-row {
  display: flex;
  gap: 32px;
  flex-wrap: wrap;
}

.info-row .info-item {
  flex: 1;
  min-width: 200px;
}

.headers-list {
  max-height: 200px;
  overflow-y: auto;
}

.header-item {
  padding: 8px 0;
  border-bottom: 1px solid #ebeef5;
  color: #606266;
}

.header-item:last-child {
  border-bottom: none;
}

.request-body,
.response-body {
  font-family: 'Courier New', monospace;
}
</style>
